package com.nicolasprof.profgallery.viewer {
	import com.hexagonstar.util.debug.Debug;
	import com.nicolasprof.profgallery.preloader.Preloader;

	import flash.display.*;
	import flash.events.*;
	import flash.geom.Matrix;
	import flash.geom.Rectangle;
	import flash.net.URLRequest;

	/**
	 * @author Nicolas Prof
	 */
	public class Viewer extends Sprite {
		
		private var _loader:Loader;
		private var _bmpLayer:Bitmap;
		private var _bitmapData:BitmapData;
		private var _imageHolder: Sprite;
		private var _preloader : Preloader;
		private var _previousURL : String;
		private var _width : int;
		private var _height : int;
		
		public function Viewer() {
		}
		override public function dispatchEvent(e:Event):Boolean {
		 	if (hasEventListener(e.type) || e.bubbles) {
		  		return super.dispatchEvent(e);
		  	}
		 	return true;
		}
		public function initiate(width : int, height: int, baseloader : Preloader = null) : void {
			_width = width;
			_height = height;
			_imageHolder = new Sprite();
			_loader=new Loader();
			_bitmapData = new BitmapData(_width, _height, true, 0xFFFFFF);
			_bmpLayer = new Bitmap(_bitmapData,"auto",true);
			_previousURL = "";

			//DISPLAY LIST
			_imageHolder.addChild(_bmpLayer);
			addChild(_imageHolder);
			
			//LISTENERS
			_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete, false, 0 , true);
			_loader.contentLoaderInfo.addEventListener(Event.OPEN, onOpenImage, false, 0 , true);
			_loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onLoading, false, 0 , true);
			_loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
			
			//ACTIONS
			preloader = baseloader;
		}

		public function loadImage(url:String) : Boolean {
			if (_previousURL != url) {
				if(_preloader != null){
					_preloader.progress = 0;
					_preloader.toggle(true);
				}
				var request:URLRequest = new URLRequest(url);
				_previousURL = url;
				_loader.load(request);
				return true;
			}	
			return false;
		}
		
		public function reset() : void {
			_bitmapData.fillRect(new Rectangle(0, 0, _width,_height), 0x00000000);
		}
		
		/**
		 * EVENTS
		 */ 
		private function onComplete(e : Event) : void {
			var bitmap : Bitmap = e.currentTarget.content;
			var ratio : Number = Math.min(_width / bitmap.width, _height / bitmap.height);
			ratio = Math.min(ratio,1); //Comment this line to enlarge small images to size of Viewer
			bitmap.smoothing = true;
			var matrix : Matrix = new Matrix(ratio,0,0, ratio);
			matrix.tx = (_width - bitmap.width * ratio) >> 1;
			matrix.ty = (_height - bitmap.height * ratio) >> 1;
			
			_bitmapData.fillRect(new Rectangle(0,0,_width,_height), 0x00000000);
			_bitmapData.draw(bitmap, matrix);	
			
			if(_preloader != null){
				_preloader.toggle(false);
			}
			dispatchEvent(e);
			
		}
		private function onIOError(e : IOErrorEvent) : void {
			Debug.trace("IOError: " + e.toString());
			dispatchEvent(e);
		}

		private function onOpenImage(e : Event) : void {
			dispatchEvent(e);
		}
		private function onLoading(e:ProgressEvent):void {
			if(_preloader != null){
				_preloader.progress = (e.bytesLoaded / e.bytesTotal);
			}
			dispatchEvent(e);
		}


		/**
		 * GETTERS AND SETTERS
		 */
		public function get bitmapData() : BitmapData {
			return _bitmapData;
		}
		public function set bitmapData(value : BitmapData) : void {
			_bitmapData = value;
			_bmpLayer.bitmapData = _bitmapData;
			_bmpLayer.smoothing = true;
		}
		public function set preloader(obj : Object) : void {
			if(obj == null) return;
			_preloader = new obj();
			_preloader.x = _width>>1;
			_preloader.y = _height>> 1;
			_preloader.initiate();
			_preloader.toggle(false, 0);
		}
		override public function set scaleX(value : Number) : void {
			super.scaleX = value;
			this.x = int((_width - this.width) >> 1);
		}
		override public function set scaleY(value : Number) : void {
			super.scaleY = value;
			this.x = int((_height - this.height) >> 1);
		}
		public function get url() : String {
			return _previousURL;
		}
	}
}
